home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Directorty Opus 5 - Magellan
/
Opus 5 - Magellan.iso
/
Extras
/
D51_NUSource
/
Source
/
Routines
/
NIB.s
< prev
next >
Wrap
Text File
|
1995-09-26
|
20KB
|
480 lines
***************************************************************************************
* Nudel-Info-Block (NIB) Routines *
***************************************************************************************
;=====================================================================================;
; NudelInfoBlock Subroutines. ;
;=====================================================================================;
;NIBR_ALLOCATE ; (De)Allocate memory
;NIBR_OPEN ; DOS/(Open|Close)
;NIBR_LOCK ; DOS/(Un)Lock
;NIBR_EXAMINE ; DOS/(Un)Examine (allocates FileInfoBlock)
;NIBR_NREAD ; Read a file into memory (creates and fills in a new NIB).
; Include ASM:Source/Routines/NIB.s
;=====================================================================================;
; NUDEL-INFO-BLOCK STRUCTURE ;
;=====================================================================================;
;See ASM:Include/Constants.i
***********************************************************************= 12-Aug-1995 =*
* Create a new NIB *
*=====================================================================================*
* Inputs: Various NIB pointers. *
* Outputs: Various NIB pointers updated. *
* Active_NIB(a5) = Address of new NIB. *
* Notes: Assume all registers apart from d0/a0 destroyed. *
* Program will abort if allocation fails. *
***************************************************************************************
Create_NIB
Moveq #NIB_SizeOf,d0 Size of NIB structure.
Lea IDS_FileName(pc),a0 -._ Set pseudo-filename.
Move.l a0,NIB_NameAdrs+FakeNIB(a5) -' in fake NIB.
Bsr LeoAllocPooled -.
Tst.l d0 |- Get mem, quit on failure.
Beq_ErrorE ErrAct_AllocMem(pc),FakeNIB_Adrs(a5)
Sub.l d1,d1 -.
Move.l d0,a0 |
Move.l d1,NIB_Next(a0) |
;;;;;;; Move.l d1,NIB_Previous(a0) |
Move.l d1,NIB_MemSize(a0) |_ Initialise
Move.l d1,NIB_MemAdrs(a0) | the structure.
Move.l d1,NIB_NameAdrs(a0) |
Move.l d1,NIB_Handle(a0) |
Move.l d1,NIB_Lock(a0) |
Move.l d1,NIB_FIB(a0) -'
Move.l Last_NIB(a5),NIB_Previous(a0) Pointer to old last NIB.
Bne.s CNIB_S1 -._ If null, this
Move.l a0,Base_NIB(a5) -' is the base NIB.
Bra.s CNIB_S2
CNIB_S1 Move.l NIB_Previous(a0),a1 -._ Update "next" pointer
Move.l a0,NIB_Next(a1) -' in previous NIB.
CNIB_S2 Move.l a0,Last_NIB(a5) This is now the last NIB.
Move.l a0,Active_NIB(a5) Set Active NIB.
RTS
IDS_FileName
Dc.b "internal data structure"
Even
***********************************************************************= 11-Aug-1995 =*
* Delete ALL NIBs *
*=====================================================================================*
* Notes: Assume all registers apart are destroyed. *
***************************************************************************************
NIBs_DeleteAll
Bra.s NIBs_DelStart
NIBs_DelMore
Move.l d0,Active_NIB(a5) ...make it "Active" for Deletion.
Bsr.s Delete_NIB Delete this NIB, update Ptrs.
NIBs_DelStart
Move.l Base_NIB(a5),d0 Get current Base NIB...
Bne.s NIBs_DelMore If all Freed, routine completed.
RTS
***********************************************************************= 12-Aug-1995 =*
* Delete a NIB *
*=====================================================================================*
* Inputs: Active_NIB(a5) = Pointer to NIB to delete. *
* Outputs: Various NIB pointers updated. *
* Active_NIB(a5) = NULL *
* Notes: Assume all registers apart are destroyed. *
* If extra memory was allocated for the filename, _you_ must be free it. *
* (You should allocate this mem as a NIB and thus have it auto-freed) *
***************************************************************************************
Delete_NIB
Tst.l Active_NIB(a5) -.
Bne.s Delete_NIB_Skip |- No NIB? Skip routine.
RTS -'
Delete_NIB_Skip
IFD NIBR_ALLOCATE -.
Bsr Deallocate_NIB |- Free memory if allocated.
ENDC -'
IFD NIBR_OPEN -.
Bsr Close_NIB |- Close if openned.
ENDC -'
IFD NIBR_LOCK -.
Bsr UnLock_NIB |- Unlock if locked.
ENDC -'
IFD NIBR_EXAMINE -.
Bsr UnExamine_NIB |- Free FileInfoBlock if allocated.
ENDC -'
Move.l Active_NIB(a5),a1
Move.l #0,Active_NIB(a5) No active NIB anymore.
Move.l NIB_Previous(a1),a0 a0 = Previous NIB
;;;;;;; a1 = This NIB
Move.l NIB_Next(a1),a2 a2 = Next NIB
Delete_NIB_DeLink
Tst.l NIB_Previous(a1) A previous NIB?
Beq.s Delete_NIB_NoPrev If not, jump
Delete_NIB_Prev
Tst.l NIB_Next(a1) A next NIB?
Beq.s Delete_NIB_Prev_NoNext If not, jump
Delete_NIB_Prev_Next
Move.l a2,NIB_Next(a0)
Move.l a0,NIB_Previous(a2)
Bra.s Delete_NIB_DeLinked
Delete_NIB_Prev_NoNext
Move.l a0,Last_NIB(a5)
Move.l a2,NIB_Next(a0) (a2 = 0)
Bra.s Delete_NIB_DeLinked
Delete_NIB_NoPrev
Tst.l NIB_Next(a1) A next NIB?
Beq.s Delete_NIB_NoPrev_NoNext If not, jump
Delete_NIB_NoPrev_Next
Move.l a2,Base_NIB(a5)
Move.l a0,NIB_Previous(a2) (a0 = 0)
Bra.s Delete_NIB_DeLinked
Delete_NIB_NoPrev_NoNext
Move.l a0,Base_NIB(a5) (a0 = 0)
Move.l a0,Last_NIB(a5) (a0 = 0)
;;;;;;; Bra.s Delete_NIB_DeLinked
Delete_NIB_DeLinked
;;;;;;; Move.l a1,a1 -.
Moveq #NIB_SizeOf,d0 |- Free the NIB itself.
Bra LeoFreePooled -'
;;;;;;; RTS for us.
IFD NIBR_ALLOCATE
***********************************************************************= 22-Jul-1995 =*
* Allocate for a NIB *
*=====================================================================================*
* Inputs: Active_NIB(a5)/NIB_MemSize = Size of memory to be allocated. *
* Outputs: Active_NIB(a5)/NIB_MemAdrs = Address of allocated memory. *
* Notes: Assume all registers apart are destroyed. *
* Program will abort if allocation fails. *
***************************************************************************************
Allocate_NIB
Move.l Active_NIB(a5),a0
Tst.l NIB_MemAdrs(a0) -._ Internal error if NIB already
Bne Internal -' has memory allocated.
Move.l NIB_MemSize(a0),d0 Size of allocation to d0.
;;;;;;; Tst.l d0 -._ If zero bytes specified,
Beq Internal -' internal error.
Bsr LeoAllocPooled -.
Tst.l d0 |- Get mem, quit on failure.
Beq_ErrorE ErrAct_AllocMem(pc),Active_NIB(a5)
Move.l Active_NIB(a5),a0
Move.l d0,NIB_MemAdrs(a0) Store address in NIB.
RTS
***********************************************************************= 22-Jul-1995 =*
* Deallocate for a NIB *
*=====================================================================================*
* Inputs: Active_NIB(a5)/NIB_MemSize = Size of memory to be allocated. *
* Active_NIB(a5)/NIB_MemAdrs = Address of allocated memory. *
* Outputs: Active_NIB(a5)/NIB_MemSize = Null. *
* Active_NIB(a5)/NIB_MemAdrs = Null. *
* Notes: Assume all registers apart are destroyed. *
***************************************************************************************
Deallocate_NIB
Move.l Active_NIB(a5),a0
Move.l NIB_MemSize(a0),d0 -.
;;;;;;; Tst.l d0 |
Beq.s Deallocate_NIB_Skip |_ Skip if memory
Move.l NIB_MemAdrs(a0),d1 | not allocated.
;;;;;;; Tst.l d1 |
Beq.s Deallocate_NIB_Skip -'
Move.l d1,a1
Bra LeoFreePooled Free memory.
;;;;;;; RTS for us.
Deallocate_NIB_Skip
RTS
ENDC
IFD NIBR_OPEN
***********************************************************************= 26-Sep-1995 =*
* Open for a NIB *
*=====================================================================================*
* Inputs: Active_NIB(a5)/NIB_NameAdrs = Address of null-term filename to open. *
* d2 = #Mode_Old or #Mode_New *
* d7 = Temp storage.
* Outputs: Active_NIB(a5)/NIB_Handle = Handle of opened file. *
* d0 = Null if failure. *
* Notes: Assume all registers apart are destroyed. *
* _You_ must handle error (d0 = #0) yourself. *
***************************************************************************************
Open_NIB
Move.w #3,d7 Maximum number of 3 retries.
Move.l Active_NIB(a5),a0 -.
Tst.l NIB_Handle(a0) |- Internal error if NIB already open.
Bne Internal -'
Open_NIB_Retry
Move.l Active_NIB(a5),a0
Move.l NIB_NameAdrs(a0),d1 -.
;;;;;;; Tst.l d1 |- Error if no filename to open.
Beq Internal -'
;;;;;;; Move.l d1,d1 NameAdrs into d1.
;;;;;;; Move.l d2,d2 Mode into d2.
Movem.l d2/d7,-(SP) Preserve mode & nº retries.
N_CallDOS Open Open file.
Movem.l (SP)+,d2/d7 Restore mode & nº retries.
;;;;;;; Note: The only error handled is File-in-use, the calling routine MUST CHECK d0.
Tst.l d0 Check for error
Bne.s Open_NIB_InUseSkip -._ If max retries done,
DBra d7,Open_NIB_InUse -' pass it through.
Open_NIB_InUse_MaxTries
Moveq #0,d0
Open_NIB_InUseSkip
Move.l Active_NIB(a5),a0
Move.l d0,NIB_Handle(a0) Store filehandle.
RTS
;-------------------------------------------------------------------------------------;
Open_NIB_InUse
Movem.l d2/d7,-(SP) Preserve mode & nº retries.
N_CallDOS IoErr Get error return code into d0
Movem.l (SP)+,d2/d7 Restore mode & nº retries.
Cmpi.l #ERROR_OBJECT_IN_USE,d0 -._ If it's any error other than "in use",
Bne.s Open_NIB_InUse_MaxTries -' drop it through to the calling routine.
Movem.l d2/d7,-(SP) Preserve mode & nº retries.
Move.l #250,d1 -._ Wait
N_CallDOS Delay -' 5 Secs.
Movem.l (SP)+,d2/d7 Restore mode & nº retries.
Bra.s Open_NIB_Retry
***********************************************************************= 22-Jul-1995 =*
* Close for a NIB *
*=====================================================================================*
* Inputs: Active_NIB(a5)/NIB_Handle = Handle of opened file. *
* Outputs: Active_NIB(a5)/NIB_Handle = Null. *
* Notes: Assume all registers are destroyed. *
* Errors are handled automatically (jump to error routine). *
***************************************************************************************
Close_NIB
Move.l Active_NIB(a5),a0 a0 = active NIB.
Move.l NIB_Handle(a0),d1 Handle to d1.
Move.l #0,NIB_Handle(a0) Mark as closed (MUST be before ErrorE).
Tst.l d1 -._ Skip if handle
Beq.s Close_NIB_Skip -' not open.
N_CallDOS Close Close the file.
Tst.l d0 -._ If error, it's fatal.
Beq_ErrorE ErrAct_Close(pc),Active_NIB(a5)
Close_NIB_Skip
RTS
ErrAct_Close
Dc.b "Could not close ",0
Even
ENDC
IFD NIBR_LOCK
***********************************************************************= 26-Sep-1995 =*
* Lock for a NIB *
*=====================================================================================*
* Inputs: Active_NIB(a5)/NIB_NameAdrs = Address of null-term filename to lock. *
* d2 = #ACCESS_READ, or #ACCESS_WRITE *
* d7 = Temp storage.
* Outputs: Active_NIB(a5)/NIB_Lock = Lock of locked object. *
* d0 = Null if failure. *
* Notes: Assume all registers are destroyed. *
* _You_ must handle error (d0 = #0) yourself. *
***************************************************************************************
Lock_NIB
Move.w #3,d7 Maximum number of 3 retries.
Move.l Active_NIB(a5),a0 -.
Tst.l NIB_Lock(a0) |- Internal error if NIB already locked.
Bne Internal -'
Lock_NIB_Retry
Move.l Active_NIB(a5),a0
Move.l NIB_NameAdrs(a0),d1 -.
;;;;;;; Tst.l d1 |- Error if no filename to lock.
Beq Internal -'
;;;;;;; Move.l d1,d1 NameAdrs into d1.
;;;;;;; Move.l d2,d2 Mode into d2.
Movem.l d2/d7,-(SP) Preserve mode & nº retries.
N_CallDOS Lock Lock the object.
Movem.l (SP)+,d2/d7 Restore mode & nº retries.
;;;;;;; Note: The only error handled is File-in-use, the calling routine MUST CHECK d0.
Tst.l d0 Check for error
Bne.s Lock_NIB_InUseSkip -._ If max retries done,
DBra d7,Lock_NIB_InUse -' pass it through.
Lock_NIB_InUse_MaxTries
Moveq #0,d0
Lock_NIB_InUseSkip
Move.l Active_NIB(a5),a0
Move.l d0,NIB_Lock(a0) Store lock.
RTS
Lock_NIB_InUse
Movem.l d2/d7,-(SP) Preserve mode & nº retries.
N_CallDOS IoErr Get error return code into d0
Movem.l (SP)+,d2/d7 Restore mode & nº retries.
Cmpi.l #ERROR_OBJECT_IN_USE,d0 -._ If it's any error other than "in use",
Bne.s Lock_NIB_InUse_MaxTries -' drop it through to the calling routine.
Movem.l d2/d7,-(SP) Preserve mode & nº retries.
Move.l #250,d1 -._ Wait
N_CallDOS Delay -' 5 Secs.
Movem.l (SP)+,d2/d7 Restore mode & nº retries.
Bra.s Lock_NIB_Retry
ErrAct_Lock
Dc.b "Could not lock ",0
Even
***********************************************************************= 12-Aug-1995 =*
* UnLock for a NIB *
*=====================================================================================*
* Inputs: Active_NIB(a5)/NIB_Lock = Lock of locked object. *
* Outputs: Active_NIB(a5)/NIB_Lock = Null. *
* Notes: Assume all registers are destroyed. *
***************************************************************************************
UnLock_NIB
Move.l Active_NIB(a5),a0 a0 = active NIB.
Move.l NIB_Lock(a0),d1 Lock to d1
Move.l #0,NIB_Lock(a0) Mark as unlocked (MUST be before ErrE).
Tst.l d1 -._ Skip if object
Beq.s UnLock_NIB_Skip -' not locked.
N_CallDOS UnLock UnLock the object.
UnLock_NIB_Skip
RTS
ENDC
IFD NIBR_EXAMINE
***********************************************************************= 26-Sep-1995 =*
* Examine for a NIB *
*=====================================================================================*
* Inputs: Active_NIB(a5)/NIB_Lock = Lock of locked object. *
* Outputs: Active_NIB(a5)/NIB_FIB = Pointer to filled in FileInfoBlock. *
* Notes: Assume all registers are destroyed. *
* : Errors are handled automatically by this routine. *
***************************************************************************************
Examine_NIB
Move.l Active_NIB(a5),a0 -.
Tst.l NIB_FIB(a0) |- Internal error if NIB already examined.
Bne Internal -'
Lea IDS_FileName(pc),a0 -._ Set pseudo-filename in fake NIB
Move.l a0,NIB_NameAdrs+FakeNIB(a5) -' to "internal data structure".
Moveq #DOS_FIB,d1 Want to Allocate a FileInfoBlock.
Moveq #0,d2 No tags.
N_CallDOS AllocDosObject Allocate it.
Move.l Active_NIB(a5),a0 -._ Store pointer to
Move.l d0,NIB_FIB(a0) -' the FileInfoBlock.
Beq_ErrorE ErrAct_AllocMem(pc),FakeNIB_Adrs(a5)
;;;;;;; Move.l Active_NIB(a5),a0
Move.l NIB_Lock(a0),d1 File lock for Examine()
Move.l d0,d2 FileInfoBlock for Examine()
N_CallDOS Examine Examine the file.
Tst.l d0
Beq_ErrorE ErrAct_Examine(pc),Active_NIB(a5)
RTS
ErrAct_Examine
Dc.b "Could not examine ",0
Even
***********************************************************************= 26-Sep-1995 =*
* UnExamine for a NIB (Frees the FileInfoBlock) *
*=====================================================================================*
* Inputs: Active_NIB(a5)/NIB_FIB = Allocated FileInfoBlock. *
* Outputs: Active_NIB(a5)/NIB_FIB = NULL (FileInfoBlock is freed). *
* Notes: Assume all registers are destroyed. *
***************************************************************************************
UnExamine_NIB
Move.l Active_NIB(a5),a0 -.
Move.l NIB_FIB(a0),d2 |_ Skip routine if FIB
Bne.s UnExamine_NIB_DoIt | hasn't been allocated.
RTS -'
UnExamine_NIB_DoIt
Moveq #DOS_FIB,d1 Want to Free a FileInfoBlock.
;;;;;;; Move.l d2,d2 Pointer to FIB to be freed.
N_JumpDOS FreeDosObject Free it.
;;;;;;; RTS for us.
ENDC
IFD NIBR_NREAD
***********************************************************************= 26-Sep-1995 =*
* NRead_NIB: Reads a file into memory, creating and filling in a new NIB. *
*=====================================================================================*
* Inputs: a1 - Pointer to filename to read into memory. *
* Outputs: d0 - Boolean success. *
* On failure ONLY: The given filename is put into FakeNIB for you. *
* Active_NIB(a5) - Pointer to the new NIB for the file. *
* Active_NIB(a5)/NIB_FIB - Pointer to filled-in FileInfoBlock for file. *
* Active_NIB(a5)/NIB_MemSize - Size of memory allocated (equal to filesize) *
* Active_NIB(a5)/NIB_MemAdrs - Pointer to memory containing the file. *
* Notes: Failure will only occur if a DOS routine fails, so Ioerr()'s result is *
* valid after calling this routine. *
* : When the file is finished with, you can use Delete_NIB as "UnRead_NIB". *
* : The file will NOT be locked or open after the routine is done. *
* : If the file is empty the program will output an error message and abort. *
* : Assume all registers destroyed. *
***************************************************************************************
NRead_NIB
Move.l a1,-(SP) Preserve pointer to filename.
Bsr Create_NIB Create a new NIB for this file.
;;;;;;; (Errors handled automatically)
Move.l (SP)+,a1 Restore pointer to filename.
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
Move.l Active_NIB(a5),a0 -._ Put pointer to filename
Move.l a1,NIB_NameAdrs(a0) -' into the NIB structure.
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
Moveq #ACCESS_READ,d2 -._ Lock() the file
Bsr Lock_NIB -' with READ mode.
Tst.l d0 -._ If it failed,
Beq.s NRead_NIB_Failure -' abort the routine.
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
Bsr Examine_NIB Allocate and fill-in the FileInfoBlock
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
Move.l Active_NIB(a5),a0 -.
Move.l NIB_FIB(a0),a1 |- Want to allocate enough space to
Move.l fib_Size(a1),NIB_MemSize(a0) -' load the entire file in to memory.
Beq_ErrorE ErrAct_EmptyFile(pc),Active_NIB(a5)
;;;;;;; (The Finish routine will delete the NIB, there's no need to worry about it).
Bsr Allocate_NIB Allocate the memory for the file.
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
Move.l #MODE_OLDFILE,d2 -._ Open the file
Bsr Open_NIB -' (must already exit).
Tst.l d0 -._ If it failed,
Beq.s NRead_NIB_Failure -' abort the routine.
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
Bsr UnLock_NIB Don't need the lock anymore, so UnLock file.
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
Move.l Active_NIB(a5),a0
Move.l NIB_Handle(a0),d1 Handle to read from,
Move.l NIB_MemAdrs(a0),d2 Memory to read into,
Move.l NIB_MemSize(a0),d3 Amount to read (filesize and memory size).
N_CallDOS Read Read the file into memory.
Cmpi.l #-1,d0 (Read returns -1 for error!)
Beq.s NRead_NIB_Failure
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
Bsr Close_NIB Close the file.
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
Moveq #1,d0 Indicate success.
RTS
;-------------------------------------------------------------------------------------;
NRead_NIB_Failure
Move.l Active_NIB(a5),a0 Put filename into FakeNIB automatically.
Move.l NIB_NameAdrs(a0),NIB_NameAdrs+FakeNIB(a5)
Bsr Delete_NIB Delete the NIB.
Moveq #0,d0 Indicate failure.
RTS
;-------------------------------------------------------------------------------------;
ErrAct_Read
Dc.b "Could not read ",0
ErrAct_EmptyFile
Dc.b "File is empty: ",0
Even
ENDC